﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using Silvermoon.Controls;
using Passwords.Models;
using Silvermoon.Windows.Styles;
using Passwords.Controllers;
using Silvermoon.Images;
using Passwords.Images;
using Silvermoon.UI;
using Silvermoon.Navigation;
using Passwords.Utils;
using Silvermoon.Shapes;
using Passwords.Biz;
using Silvermoon.OpenGL;
using Silvermoon.Controls.Forms;
using Silvermoon.Windows;
using System.Collections;
using System.IO;

namespace Passwords.Pages
{

    /// <summary>
    /// Edits the details of a password.
    /// In this case, no ListViewController is used, as the item type varies, so item recycling makes no sense.
    /// </summary>
    public class EditDetailsPage : Page
    {
        object categoryItem = new object();
        object isFaveItem = new object();
        static PasswordItem ItemToShow;
        private Password password;
        private ListView listView;
        private TextBox textBox;
        private Toolbar toolbar;

        public EditDetailsPage()
            : base()
        {
            InitializePage();
        }

        protected override void Dispose(bool dispose)
        {
            if (Context.Current != null)
            {
                Context.Current.PasswordSaved -= OnOk;
            }
            Password = null;
            base.Dispose(dispose);
        }

        public Password Password
        {
            get { return password; }
            set
            {
                if (password != value)
                {
                    password = value;
                    OnPasswordChanged();
                }
            }
        }

        private void InitializePage()
        {
            Styles = StylePool.Metro;
            SetTransition(350, TransitionMask.Fade | TransitionMask.Explode, TransitionMask.Fade | TransitionMask.Explode);
            Title = "PASSWORDS < DETAILS < EDIT";

            textBox = new TextBox { Margin = new Margin(6, 6, 6, null), Height = 64, AcceptReturn = false, Watermark = new StringShape { Text = "Enter name", Opacity = 140 } };
            textBox.TextChanged += new EventHandler(OnTextChanged);
            listView = new ListView { Margin = new Margin(0, 80, 0, 0), KeepItems = true, ItemHeight = 110 };
            listView.GetVirtualItem += new EventHandler<ItemEventArgs>(OnGetVirtualItem);
            listView.Styles.SetClass<TitleDetailsImageItem>(new TitleDetailsImageItemStyle { TitleFont = FontCache.MediumRegularFont, Margin = new Margin(0, 0, 24, 10) });
            Controls.Add(listView, textBox);


            toolbar = new Toolbar();

            toolbar.Styles.SetClass<MenuItem>(new TextItemStyle { Font = FontCache.MediumRegularFont, Padding = new Margin(20, 0, 20, 0) });
            toolbar.Buttons.Add(new ToolbarButton(ImagePool.Save, PasswordCommands.SavePassword));
            toolbar.AddButton(SysImages.Add).Tap += OnAddLabel;
            toolbar.Buttons.Add(new ToolbarButton(SysImages.Cancel, Page.BackCommand));
            toolbar.AddMenuItem("Add Label").Tap += OnAddLabel;
            toolbar.AddMenuItem("Delete password", PasswordCommands.DeletePassword);
            toolbar.AddMenuItem("Change Categories").Tap += new EventHandler<TapEventArgs>(OnChangeCategories);
            this.Toolbar = toolbar;

            Context.Current.PasswordSaved += OnOk;
            Style = StylePool.EditWindow;
        }

        void OnGetVirtualItem(object sender, ItemEventArgs e)
        {
            object value = e.Value;
            if (value == categoryItem) GetCategoryPasswordItem(e);
            //else if (value is CategoryPasswordItem) GetPasswordItem(e);
            else if (value is PasswordItem) GetPasswordItem(e, value as PasswordItem);
            else if (value == isFaveItem) GetFaveItem(e);
            else GetPasswordItem(e);
        }

        private void GetFaveItem(ItemEventArgs e)
        {

            ContainerItem item = new ContainerItem();
            CheckBox cb = new CheckBox
            {
                Background=PhoneColors.Orange,
                Margin = new Margin(8, 8, 8, null),
                Height = 64,
                Content = new StringShape { Text = "Is favorite", Font = FontCache.MediumRegularFont, Color = PhoneColors.White },
                IsChecked = password.IsFavorite,
                TextColor = PhoneColors.White
            };
            cb.CheckedChanged += new EventHandler(cb_CheckedChanged);
            item.Control = cb;
            e.Item = item;
        }

        void cb_CheckedChanged(object sender, EventArgs e)
        {
            CheckBox cb = sender as CheckBox;
            password.IsFavorite = cb.IsChecked;
        }

        private void GetCategoryPasswordItem(ItemEventArgs e)
        {
            TitleDetailsImageItem item = new TitleDetailsImageItem();
            item.Tap += OnChangeCategories;
            item.Title = "Add Categories";
            item.TitleLineAlignment = Alignment.Center;
            item.Image = SysImages.Add;
            item.ImageBackground = SysImages.Circle;
            //ContainerItem item = new ContainerItem();
            //Button btn = new Button { Margin = new Margin(8, 8, 8, null), Height = 64, Content = "Categories" };
            //btn.Tap += OnChangeCategories;
            //item.Control = btn;
            e.Item = item;
        }

        private void GetPasswordItem(ItemEventArgs e)
        {
            var item = new ContainerItem { AutoHeight = true, Height = 1 };
            e.Item = item;
        }

        private void GetPasswordItem(ItemEventArgs e, PasswordItem data)
        {
            TitleDetailsImageItem item = new TitleDetailsImageItem();
            item.Tap += new EventHandler<TapEventArgs>(OnItemTap);
            item.Image = data.IsEmpty ? SysImages.Add : null;
            if (data.IsEmpty)
            {
                item.TitleLineAlignment = Alignment.Center;
                item.ImageBackground = SysImages.Circle;
            }
            else
            {
                item.TitleLineAlignment = Alignment.Near;
                item.ImageBackground = null;
            }
            item.Title = data.Name;
            item.Details = data.Value;
            e.Item = item;

        }


        void OnTextChanged(object sender, EventArgs e)
        {
            IsSaveEnabled = !string.IsNullOrEmpty(textBox.Text);
            password.Name = textBox.Text;
        }


        void OnAddLabel(object sender, EventArgs e)
        {
            LabelPickerPage page = new LabelPickerPage(this.Password);
            page.ItemChosen += new EventHandler(OnLabelChosen);
            this.NavigateTo(page);
        }

        static void OnLabelChosen(object sender, EventArgs e)
        {
            LabelPickerPage page = sender as LabelPickerPage;
            PasswordLabel label = page.SelectedLabel;
            if (label != null)
            {
                Password password = page.Password;
                var item = new PasswordItem(password, label);
                ItemToShow = item;
                password.AddItem(item);
                EditItem(item, page);
                page.NavigationService.RemoveFromStack(page);
            }
        }

        protected override void OnShowing()
        {
            base.OnShowing();
            BringItemIntoView();
        }

        protected override void OnShown()
        {
            base.OnShown();
            if (string.IsNullOrEmpty(textBox.Text)) Schedule(textBox.SetFocus);
        }

        private void BringItemIntoView()
        {
            if (ItemToShow != null)
            {

                int index = listView.ItemsSource.IndexOf(ItemToShow);
                if (index >= 0)
                {
                    listView.BringItemIntoView(index, false);
                    //     listView.SelectedItemIndex = index;
                }
                ItemToShow = null;
            }
        }

        public bool IsSaveEnabled
        {
            get { return toolbar.Buttons[0].Enabled; }
            set
            {
                if (IsSaveEnabled != value)
                {
                    toolbar.Buttons[0].Enabled = value;
                }
            }
        }

        void OnChangeCategories(object sender, TapEventArgs e)
        {
            Page page = new ChangeCategoriesPicker { PasswordItem = new CategoryPasswordItem(password) };
            this.NavigateTo(page);
        }


        void OnItemTap(object sender, TapEventArgs e)
        {
            Item item = (sender as Item);
            PasswordItem pwItem = item.DataValue as PasswordItem;

            EditItem(pwItem, this);
        }

        private static void EditItem(PasswordItem pwItem, Page root)
        {
            Page page = CreatePageFromItem(pwItem);
            root.NavigateTo(page);
        }

        private static Page CreatePageFromItem(PasswordItem pwItem)
        {
            switch (pwItem.ValueType)
            {
                case ItemType.NumericPassword:
                case ItemType.Password: return new PasswordPicker(true) { PasswordItem = pwItem };
                case ItemType.Decimal: return new StringPickerPage(true) { PasswordItem = pwItem };
                case ItemType.Time: return new TimePicker { PasswordItem = pwItem };
                case ItemType.Date: return new DatePickerPage(DatePickerMode.Date) { PasswordItem = pwItem };
                case ItemType.MonthYear: return new DatePickerPage(DatePickerMode.MonthYear) { PasswordItem = pwItem };
                case ItemType.Categories: return new ChangeCategoriesPicker { PasswordItem = pwItem };
                default: return new StringPickerPage { PasswordItem = pwItem };
            }
        }



        /// <summary>
        /// Occurs at Context.OnPasswordSaved.
        /// </summary>
        void OnOk(object sender, EventArgs e)
        {
            password.Name = textBox.Text;
            password = null;
            GoBack();
        }

        protected override void OnBack(HandledEventArgs e)
        {
            if (password != null) password.Undo();
            base.OnBack(e);
        }

        private void OnPasswordChanged()
        {
            AppController.CurrentPassword = password;
            if (password != null)
            {
                var list = password.EditItems.Where(c => !(c is CategoryPasswordItem)).Select(c => (object)c).ToList();
                if (password.Categories.Count == 0) list.Insert(0, categoryItem);
                list.Add(isFaveItem);
                listView.ItemsSource = list;
                textBox.Text = password.Name;
            }
            else
            {
                listView.ItemsSource = null;
            }
        }

        private class Bag
        {
            public string name;
            public Password Password;
            public int YOffset;
        }

        public override object OnSaveViewState()
        {
            return new Bag { YOffset = listView.YOffset, Password = password, name = textBox.Text };
        }


        public override void OnLoadViewState(object viewState)
        {
            Bag bag = viewState as Bag;
            if (bag != null)
            {
                Password = bag.Password;
                listView.YOffset = bag.YOffset;
                textBox.Text = bag.name;
            }
        }
    }
}
